其他
微前端在小米 CRM 系统的实践
你的关注意义重大!
@木子朗,小米 前端工程师,目前专注于前端架构、前端工程化,热衷于打造高质量、高性能、用户体验一流的产品。个人网站:https://www.lishuaishuai.com
Techniques, strategies and recipes for building a modern web app with multiple teams that can ship features independently. — Micro Frontends
实施微前端的六种方式
路由分发
前端微服务化
微应用
微件化
iframe
HTML 内联框架元素 <iframe>
表示嵌套的正在浏览的上下文,能有效地将另一个 HTML 页面嵌入到当前页面中。
网站不需要 SEO 支持 拥有相应的应用管理机制。
Web Components
真实的业务场景
统一的域名 统一的界面和交互 系统需要方便拓展 不希望开发阶段每个系统有独立的代码仓库 CI 构建
怎么改造?
关键点
申请统一的域名(暂且称之为crm.mi.com) 将 old-a 和 old-b 两个老旧的系统样式调整,像系统C靠拢 三个系统使用统一的菜单和权限 三个系统使用统一的 SSO C 系统和正在开发的 X 个系统使用 CI 解决打包和手动 copy 的问题
微前端几种方式对比
实施
一些问题
子应用注册方式
// single-spa-config.js
import{ registerApplication, start } from'single-spa'
registerApplication("applicationName", loadingFunction, activityFunction)
start()
function loadingFunction() {
returnimport("src/app1/main.js")
}
function activityFunction(location) {
return location.pathname.indexOf("/app1/") === 0
}
// single-spa-config.js
import* as singleSpa from'single-spa'
import config from'./manifest.json'
registerApp(config)
singleSpa.start()
function registerApp(conf) {
conf.forEach(application => {
singleSpa.registerApplication(
application.name,
() => import(`./${application.name}.app/index.js`),
pathPrefix(application.activeRule, application.strict),
)
})
}
function pathPrefix(prefix, strict) {
returnfunction(location) {
if(strict) {
return location.pathname === prefix
}
return location.pathname.startsWith(`${prefix}`)
}
}
// manifest.json
[
{
"name": "layout",
"activeRule": "/"
},
{
"name": "welcome",
"activeRule": "/",
"strict": true
},
{
"name": "iframe",
"activeRule": "/link"
},
{
"name": "app1",
"activeRule": "/app1"
},
{
"name": "app2",
"activeRule": "/app2"
}
]
共享cookie
应用之间数据共享及通信
// 应用 A
window.dispatchEvent(
newCustomEvent('iframe:change', { detail: { path: '/a/b/c'} })
)
// 应用 B
window.addEventListener('iframe:change', (event) => {
console.log(event.detail.path)
})
css隔离
postcss.plugin('postcss-plugin-namespace', function() {
returnfunction(css) {
css.walkRules(rule => {
if(rule.parent && rule.parent.type === 'atrule'&& rule.parent.name !== 'media') return
const filePath = rule.source && rule.source.input.file
const appName = /src\/(\S*?)\//.exec(filePath)[1] || ''
constnamespace= appName.split('.')[0] || ''
rule.selectors = rule.selectors.map(s => `#${namespace} ${s === 'body' ? '' : s}`)
})
}
})
js沙箱
优化体验 PWA
创建桌面图标,快速访问 Service Worker 缓存,对大文件和不经常更改的文件缓存,优化加载。
还可以做什么?
可以使用 lerna 统一管理所有项目,方便维护,或者让每个应用拥有独立的仓库,做到独立开发。 可以使用 SystemJS 实现应用的动态加载、独立部署。
总结
推荐阅读
前端微服务化解决方案 可能是你见过最完善的微前端解决方案 微前端的那些事儿 Micro Frontends https://single-spa.js.org/
— 完 —
❤️ 看完两件事
如果你觉得这篇内容对你有所帮助,我想邀请你帮我两个小忙:
点个「
在看
」,让更多的人也能看到这篇内容(喜欢不点在看,都是耍流氓 -_-)关注公众号「IT平头哥联盟」,一起进步,一起成长!
推荐阅读: